Skip to content
  • 0 Votes
    4 Posts
    578 Views
    M

    Would switching to a QAbstractListModel (you'll get roles instead of columns to define your data) and using a Repeater with a custom delegate work in your usecase?

    Whether it's a list or a table model doesn't matter much. The number of columns is fixed, so a list model (using roles instead of columns) is fine. This is actually a separate question I wanted to ask in another thread... I don't really understand the concept of "roles." I keep googling it to find more explanations but none of them make sense to me for some reason.

    The bigger issue is that I don't think I understand how to use a Repeater for this, if what I really need to do is draw something on a canvas for each of the items in the list (or for each row in the table). Can a repeater be used that way?

    That's because *Views already have the basic plumbing to connect to a model in place [...] just design a component that react to those signals.

    I think that's the part I was having trouble verbalizing, thank you for attaching the right words to it!

    Just to make sure I actually understand the methodology, let me type out a scenario and make sure it passes a sanity check. Let's say that I have my subclass of QAbstractTableModel, which, like all descendants of QAbstractItemModel, emits those signals. What I need to do is develop a QML component that connects to those signals. Here's where I'm a little weak in my understanding... It seems to me that there are two things I need to do:

    Somehow declare a model for the component, where the model is some QAbstractItemModel object in the context of my QQmlApplicationEngine Declare onDataChanged for my custom component, and it will automatically be connected to the dataChanged signal that gets emitted from that QAbstractItemModel object

    Is that correct, and if so, how do I declare the model object for my custom component? ListView and TableView do this through a delegate model, which, as I mentioned above, I'm not sure I know how to use to draw things on a canvas.

    Thanks for the help, @GrecKo and @VRonin!

  • 0 Votes
    1 Posts
    613 Views
    No one has replied
  • 0 Votes
    10 Posts
    742 Views
    fcarneyF

    Don't feel bad. I spent 3 weeks working on a solution that I eventually had to scrap and do a different way. I was really mad about it, but it was a learning experience. So in this case just check assumptions. I always have to remind myself of this.

  • 0 Votes
    1 Posts
    387 Views
    No one has replied
  • 0 Votes
    6 Posts
    2k Views
    A

    @qtLove Oops, ok I should have noticed it was in a Component. You can't link directly to properties in a component since they aren't loaded in time (this reason may not be correct, it's my assumption, I'm new to QML too).

    So the way to do this is to add a property to your root item that the component item inherits, like so:

    TestSlider.qml:

    import QtQuick 2.4 import QtQuick.Controls.Styles 1.4 import QtQuick.Controls 1.4 Slider { id:slider orientation: Qt.Vertical height: parent.height property var myRad : 8 property var myColor: "blue" property Component myHandleComp: Rectangle { radius: slider.myRad width: 20 height: 20 color: slider.myColor } style: SliderStyle { id: ss groove: Rectangle { id: rec implicitWidth:parent.height implicitHeight: 1 color: "gray" } handle: myHandleComp } }

    main.qml:

    import QtQuick 2.4 import QtQuick.Controls 1.4 Rectangle { width: 600 height: 600 color: "green" TestSlider { anchors.centerIn: parent myColor: "red" } }

    That allows me to set the color and radius without using an alias into a non-created component item. Note: I broke it out into it's own property Component during some testing I was doing, you do not need to do this. You can just put it straight into handle: YourItem { }.

  • Programmatic QML

    Unsolved QML and Qt Quick
    2
    0 Votes
    2 Posts
    1k Views
    shavS

    Hi,

    If I understand correctly you want to load some components dynamically, right? If so you can read this document.

    Also you can use Loder component for load QML file dynamically. This component can be use for load qml files from local resource or from public server.

    In my application I use this methods for load qml components dynamically:

    /** @brief Create dynamic object from QML file. * @param qml Path to QML file. * @param parent Parent instance. * @param options List of options fields. * @param onComplete Callback function which will call when qml component will be loaded.*/ function createComponentFromQMLFile(qml, parent, options, onComplete) { if(qml !== null && qml !== undefined && qml.length > 0 && parent !== null && parent !== undefined && options !== null && options !== undefined && onComplete !== null && onComplete !== undefined && onComplete instanceof Function) { var tmp = Qt.createComponent(qml); if(tmp !== null) { if(tmp.status === Component.Ready) { var itemInstance = tmp.createObject(parent, options); if(itemInstance !== null) { onComplete(itemInstance); } else { console.log("[EditorHelper] ERROR: Can't create object."); onComplete(null); } } else if (tmp.status === Component.Error) { console.log("[EditorHelper] ERROR: "+tmp.errorString()); onComplete(null); } else { tmp.statusChanged.connect(function () { if (tmp.status === Component.Ready) { var item = tmp.createObject(parent, options); if(item !== null) { onComplete(item); } else { console.log("[EditorHelper] ERROR: Can't create object."); onComplete(null); } } else if (tmp.status === Component.Error) { console.log("[EditorHelper] ERROR: "+tmp.errorString()); onComplete(null); } }); } } else { console.log("[EditorHelper] ERROR: Can't load QML file '"+qml+"'."); onComplete(null); } } else { console.log("[EditorHelper] ERROR: Incorrect parameters."); onComplete(null); } }

    usnig like this:

    options = {}; //here you can set any properties from you qml object which need to create. var qml = "qrc:/qml/Components/ErrorMessageWindow.qml"; //Path to qml file from resources for load. //appRootWnd - parent element to which you want to add you dynamic object. EditorHelper.createComponentFromQMLFile(qml, appRootWnd, options, function(wnd) { //here you can set any code which was called when objections will be created and loaded. if(wnd) { wnd.open(); } });
  • 0 Votes
    4 Posts
    1k Views
    AlperA

    @Wieland Wow.. Thanks!